<?php


namespace App\Exception;


use App\Util\ResultUtil;
use Elite\Infrastructure\Helper\Logger;
use Elite\Infrastructure\Server\HttpCode;
use Elite\Infrastructure\Server\HttpException;
use Elite\Infrastructure\Exception\DumpDieException;
use Elite\Infrastructure\Server\Message;
use Swoole\Http\Request;
use Swoole\Http\Response;
use Elite\Infrastructure\View\View;
use Throwable;

class WsExceptionHandler {

    /**
     * @var Logger
     */
    private $logger;

    /**
     * @var Message
     */
    private $connection;


    public function __construct($connection) {
        $this->logger = logger('exception_' . date("Y-m-d") . '.log');
        $this->connection = $connection;
    }

    public function handle(Throwable $throwable) {
        if ($throwable instanceof DumpDieException) {
            var_dump($throwable->getMessage());
            return;
        }

        $this->writeExceptionLog($throwable);

        if ($throwable instanceof HttpException) {
            $this->connection->push(json_encode(['cmd' => 'error', 'msg' => $throwable->getCode()]));
            return;
        }

        if ($throwable instanceof ServiceException) {
            $this->connection->push(json_encode(['cmd' => 'error', 'msg' => $throwable->getMessage()]));
            return;
        }

        // 其他错误开发环境打印异常
        if ((config('env') === 'DEV')) {
            var_dump($throwable->getMessage());
        } else {
            $this->connection->push(json_encode(['cmd' => 'error', 'msg' => HttpCode::HTTP_STATUS_INTERNAL_SERVER_ERROR]));
        }
    }

    private function writeExceptionLog(Throwable $throwable) {
        $errorList[] = "{$throwable->getMessage()} In {$throwable->getFile()} Line {$throwable->getLine()}";
        $errorList[] = "Call Stack:";
        $errorList[] = $throwable->getTraceAsString();
        $stack = implode("\r\n", $errorList);
        if ((config('env') === 'DEV')) {
            var_dump($stack);
        }
        $this->logger->error($stack);
    }

}